package cn.wolfcode.car.business.service.impl;

import cn.wolfcode.car.business.domain.BpmnInfo;
import cn.wolfcode.car.business.domain.CarPackageAudit;
import cn.wolfcode.car.business.domain.ServiceItem;
import cn.wolfcode.car.business.domain.Statement;
import cn.wolfcode.car.business.mapper.BpmnInfoMapper;
import cn.wolfcode.car.business.mapper.CarPackageAuditMapper;
import cn.wolfcode.car.business.mapper.ServiceItemMapper;
import cn.wolfcode.car.business.mapper.StatementMapper;
import cn.wolfcode.car.business.qo.CarPackageAuditQuery;
import cn.wolfcode.car.business.service.ICarPackageAuditService;
import cn.wolfcode.car.common.base.page.TablePageInfo;
import cn.wolfcode.car.common.exception.BusinessException;
import cn.wolfcode.car.common.util.Convert;
import cn.wolfcode.car.shiro.ShiroUtils;
import com.github.pagehelper.PageHelper;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.*;

@Service
@Transactional
public class CarPackageAuditServiceImpl implements ICarPackageAuditService {

    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;

    @Autowired
    private StatementMapper statementMapper;

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;

    @Autowired
    private ServiceItemMapper serviceItemMapper;

    @Autowired
    private TaskService taskService;

    @Override
    public TablePageInfo<CarPackageAudit> query(CarPackageAuditQuery qo) {
        PageHelper.startPage(qo.getPageNum(), qo.getPageSize());


        return new TablePageInfo<CarPackageAudit>(carPackageAuditMapper.selectForList(qo));
    }

    @Transactional
    @Override
    public InputStream processImg(Long id) {
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectByPrimaryKey(id);
        List<String> activeActivityIds = null;
        //判断 如果是审核中就进行高亮
        if (carPackageAudit.getStatus().equals(CarPackageAudit.STATUS_IN_ROGRESS)) {
            //设置高亮节点
            activeActivityIds = runtimeService.getActiveActivityIds(carPackageAudit.getInstanceId());
        } else {
            //空集合
            activeActivityIds = Collections.EMPTY_LIST;
        }
        //通过bpmninfo的id查询查bpmninfo
        BpmnInfo bpmnInfo = bpmnInfoMapper.selectByPrimaryKey(carPackageAudit.getBpmnInfoId());
        //根据流程定义id获取
        BpmnModel bpmnModel = repositoryService.getBpmnModel(bpmnInfo.getActProcessId());

        DefaultProcessDiagramGenerator gen = new DefaultProcessDiagramGenerator();
        //获取到流程图设置高亮
        InputStream resourceAsStream = gen.generateDiagram(bpmnModel
                , activeActivityIds
                , Collections.EMPTY_LIST,
                "宋体", "宋体", "宋体");
        return resourceAsStream;
    }

    @Transactional
    @Override
    public void cancelApply(Long id) {
        //先把这一行的数据查询出来
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectByPrimaryKey(id);
        //判断他是否是审核中
        if (!CarPackageAudit.STATUS_IN_ROGRESS.equals(carPackageAudit.getStatus())) {
            throw new BusinessException("非法操作");
        }
        //修改表为CarPacksgeAudit表的状态为撤销状态
        carPackageAuditMapper.updateByStatus(CarPackageAudit.STATUS_CANCEL, id);

        //修改serviceItem表的状态为重新调整
        serviceItemMapper.changeAuditStatus(carPackageAudit.getServiceItemId(), ServiceItem.AUDITSTATUS_INIT);

        //删除流程实例
        runtimeService.deleteProcessInstance(carPackageAudit.getInstanceId(), "删除");
    }

    @Override
    public void audit(Long id, Long auditStatus, String info) {
        //第一个参数是car的id 第二个参数,1是拒绝2是同意,第三个参数是备注
        //获取car
        CarPackageAudit carPackageAudit = carPackageAuditMapper.selectByPrimaryKey(id);

        BpmnInfo bpmnInfo = bpmnInfoMapper.selectByPrimaryKey(carPackageAudit.getBpmnInfoId());
        //校验是否是在审核中
        if (!CarPackageAudit.STATUS_IN_ROGRESS.equals(carPackageAudit.getStatus())) {
            throw new BusinessException("错误操作");
        }

        String userName = ShiroUtils.getUser().getUserName();
        if (CarPackageAudit.STATUS_PASS.equals(auditStatus)) {
            info = userName + "【同意】,批注意见:" + info;
        } else {
            info = userName + "【拒绝】,批注意见:" + info;
        }
        carPackageAudit.setInfo(carPackageAudit.getInfo() + "<br>" + info);
        //执行任务
        Task task = taskService.createTaskQuery().processInstanceId(carPackageAudit.getInstanceId()).singleResult();

        Map<String, Object> map = new HashMap<>();
        map.put("auditStatus", auditStatus);
        taskService.complete(task.getId(), map);

        //获取下一个任务的
        //同意
        if (auditStatus == 2) {
            Task task2 = taskService.createTaskQuery()
                    .processInstanceId(carPackageAudit.getInstanceId()).singleResult();
            if (task2 != null) {
                //如果有代办任务的话
                carPackageAudit.setAuditorId(Long.parseLong(task2.getAssignee()));
                //设置审核时间
                carPackageAuditMapper.updateByStatusByATime(id, CarPackageAudit.STATUS_REJECT, new Date());
            } else {
                //car的表需要把状态变成审核拒绝 并且需要添加审核时间
                serviceItemMapper.changeAuditStatus
                        (carPackageAudit.getServiceItemId(), ServiceItem.AUDITSTATUS_APPROVED);
                carPackageAudit.setStatus(CarPackageAudit.STATUS_PASS);
            }
            //如果有下一个任务的话就需要获取到下一个任务节点
        } else {
            //如果是拒绝的话就需要改改变状态
            //car的表需要把状态变成审核拒绝 并且需要添加审核时间
            serviceItemMapper.changeAuditStatus
                    (carPackageAudit.getServiceItemId(), ServiceItem.AUDITSTATUS_INIT);
            carPackageAudit.setStatus(CarPackageAudit.STATUS_REJECT);
        }
        carPackageAuditMapper.updateByPrimaryKey(carPackageAudit);
    }


}
